// MIT License
// 开源地址：https://gitee.com/co1024/AbcMvc
// Copyright (c) 2021-2023 1024
// Abc.Mvc=Furion+EF+SqlSugar+Pear layui admin.

using Furion.DynamicApiController;

namespace Abc.Application.ApiAdminServices;

/// <summary>
/// 菜单管理
/// </summary>
[ApiDescriptionSettings("ApiAdmin", Name = "ApiMenu")]
[MaApi(  controller: "ApiMenu", controllerDescription: "菜单管理", PCode = "API")]
[IgnoreAntiforgeryToken]
public class ApiMenuService : IDynamicApiController
{
    private readonly ILogger<ApiMenuService> _logger;
    private readonly ISqlSugarClient _db;

    public ApiMenuService(ILogger<ApiMenuService> logger
    , ISqlSugarClient db)
    {
        _logger = logger;
        _db = db;
    }

    /// <summary>
    /// 新增或更新一条
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [MaPermission(name: "新增或更新一条", actions: "InsertOrUpdate")]
    public async Task InsertOrUpdate(ApiMenuInput input)
    {
        if (input.Id > 0)
        {
            var dbentity = await _db.Queryable<SysMenu>().FirstAsync(r => r.Id == input.Id);
            input.Adapt(dbentity);
            dbentity.IsAutoGeneration = false;//修改后，设置为不是自动生成，防止下次生成覆盖
            dbentity.Icon = $"layui-icon {dbentity.Icon}";
            await _db.UpdateAsync(dbentity);
        }
        else
        {
            var add = input.Adapt<SysMenu>();
            add.Icon = $"layui-icon {add.Icon}";
            var newEntity = await _db.InsertRsIdAsync<SysMenu>(add);
        }
    }

    /// <summary>
    /// 删除一条
    /// </summary>
    /// <param name="id"></param>
    [MaPermission(name: "删除一条", actions: "Delete")]
    public async Task Delete(long id)
    {
        var dbmenu = await _db.Queryable<SysMenu>().FirstAsync(o => o.Id == id);
        if (dbmenu.IsSystem == false)
        {
            await _db.Deleteable<SysMenu>().Where(o => o.Id == id).ExecuteCommandAsync();
        }
        else
        {
            Oops.Bah("系统菜单不能删除");
        }
    }

    /// <summary>
    /// 批量假删除
    /// </summary>
    /// <param name="ids">需要删除的数据，多条以英文逗号隔开</param>
    [MaPermission(name: "批量假删除", actions: "BatchFakeDelete")]
    public async Task BatchFakeDelete(string ids)
    {
        //这个地方要注意，还没经过测试，不确定是否会触发AOP新增和修改
        await _db.FakeDeleteAsync<SysMenu>(ids);
    }

    /// <summary>
    /// 查询一条[跟踪实体]
    /// </summary>
    /// <param name="id"></param>
    [MaPermission(name: "查询一条", actions: "Get")]
    public async Task<ApiMenuOut> Get(long id)
    {
        var dbentity = await _db.Queryable<SysMenu>().FirstAsync(o => o.Id == id);
        if (dbentity == null) return null;
        return dbentity.Adapt<ApiMenuOut>();
    }

    /// <summary>
    /// 查询一条[跟踪实体]
    /// </summary>
    /// <param name="code"></param>
    [MaPermission(name: "查询一条", actions: "GetByCode")]
    public async Task<ApiMenuOut> GetByCode(string code)
    {
        SysMenu entity = await _db.Queryable<SysMenu>().FirstAsync(o => o.Code == code);
        return entity?.Adapt<ApiMenuOut>();
    }

    /// <summary>
    /// 分页查询
    /// </summary>
    /// <param name="searchQuery"></param>
    /// <returns></returns>
    [MaPermission(name: "分页查询", actions: "GetAllByPage")]
    public async Task<PagedList<ApiMenuOut>> GetAllByPageToLayui(ApiMenuQuery searchQuery)
    {
        var queryable = _db.Queryable<SysMenu>();

        if (!string.IsNullOrWhiteSpace(searchQuery.AreaName))
        {
            var kw = searchQuery.AreaName.ToLower();
            queryable = queryable.Where(o => o.Area != null && o.Area.ToLower() == kw);
        }

        if (!string.IsNullOrWhiteSpace(searchQuery.KeyWords))
        {
            var kw = searchQuery.KeyWords.ToLower();
            queryable = queryable.Where(o => o.Name.Contains(kw)
|| (o.Code != null && o.Code.ToLower().Contains(kw))
|| (o.Url != null && o.Url.ToLower().Contains(kw)));
        }

        var resultpage = queryable.OrderByDescending(o => o.Id);
        //foreach (var item in resultpage.data)
        //{
        //    // item.PermissionStr = entities.First(o => o.Id == item.Id).Permissions?.Select(o => o.Name)?.StringJoin(",") ?? "";
        //}

        return await resultpage.ToPagedListAsync<SysMenu, ApiMenuOut>(searchQuery.Page, searchQuery.Limit);
    }

    /// <summary>
    /// 设置状态
    /// </summary>
    /// <param name="id"></param>
    /// <param name="state"></param>
    /// <param name="field">字段名</param>
    /// <returns></returns>
    [MaPermission(name: "设置状态", actions: "SetState")]
    public async Task SetState(long id, bool state, string field)
    {
        await _db.Updateable<SysMenu>()
             .SetColumnsIF(field.ToLower() == "isenable", it => it.IsEnable == state)
             .SetColumnsIF(field.ToLower() == "isexpand", it => it.IsExpand == state)
             .SetColumnsIF(field.ToLower() == "isexpand", it => it.IsDisuse == state)
             .SetColumnsIF(field.ToLower() == "issystem", it => it.IsSystem == state)
             .SetColumnsIF(field.ToLower() == "isshow", it => it.IsShow == state)
             .SetColumnsIF(field.ToLower() == "isautogeneration", it => it.IsAutoGeneration == state)
             .SetColumnsIF(field.ToLower() == "isdeleted", it => it.IsDeleted == state)
             .Where(o => o.Id == id)
             .ExecuteCommandAsync();
    }

    /// <summary>
    /// 获取MenuPermission Area 集合
    /// </summary>
    /// <returns></returns>
    [MaPermission(name: "获取MenuPermission Area 集合", actions: "GetMenuAreas")]
    public async Task<List<string>> GetMenuAreas()
    {
        List<string> areas = await _db.Queryable<SysMenu>().ToListAsync(o => o.Area);
        return areas.Distinct().ToList();
    }

    /// <summary>
    /// 查询菜单下拉树
    /// </summary>
    /// <returns></returns>
    [MaPermission(name: "查询菜单下拉树", actions: "GetDtree")]
    public async Task<Dtree> GetDtree(string pid = "")
    {
        var dtreeEntities = await _db.Queryable<SysMenu>()
            .Select(o => new DtreeEntity { id = o.Code, pid = o.PCode, name = o.Name, sort = o.Sort })
            .ToListAsync();
        var dtree = dtreeEntities.GetDtree(pid);
        return dtree;
    }

    /// <summary>
    /// 获取后台左侧菜单列表
    /// </summary>
    /// <param name="area">区域</param>
    /// <returns></returns>
    [MaPermission(name: "获取后台左侧菜单列表", actions: "GetMenus")]
    public async Task<List<PearMenuItemOut>> GetMenus(string area)
    {
        var dbmenus = await _db.Queryable<SysMenu>()
           .Where(o => o.IsEnable && o.IsShow)
           .ToListAsync();
        var menus = dbmenus.Adapt<List<PearMenuItem>>();
        var rmenus = menus.GetMenus(pid: area);
        return rmenus;
    }
}